﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace LuaMemCheck
{
    public partial class LuaObjectDetail : Form
    {
        private LuaObject _luaObject;
        private SnapInfo _snapInfo;

        private LuaObjectDetailTotalInfo _luaObjectDetailTotalInfo;

        private LuaInfoListControl _refLuaInfoListControl;
        private LuaInfoListControl _childLuaInfoListControl;

        public LuaObjectDetail()
        {
            InitializeComponent();
        }

        private void LuaObjectDetail_Load(object sender, EventArgs e)
        {
            // 自己的totalinfo

            _luaObjectDetailTotalInfo = new LuaObjectDetailTotalInfo(_luaObject, _snapInfo);



            ShowDetailTotalInfo(3);

            //显示child，ref，
            _refLuaInfoListControl = new LuaInfoListControl(RefLuaInfoList);
            _childLuaInfoListControl = new LuaInfoListControl(ChildLuaInfoList);

            List<LuaObject> refLuaInfos = new List<LuaObject>();
            List<LuaObject> childLuaInfos = new List<LuaObject>();

            Dictionary<string, string> childs = _luaObject.GetChilds();
            foreach (var key in childs.Keys)
            {
                LuaObject child = _snapInfo.GetLuaObject(childs[key]);
                childLuaInfos.Add(child);
            }

            Dictionary<string, string> parents = _luaObject.GetParents();
            foreach (var key in parents.Keys)
            {
                LuaObject parent = _snapInfo.GetLuaObject(parents[key]);
                refLuaInfos.Add(parent);
            }

            Dictionary<string, string> upvalues = _luaObject.GetUpvalues();
            foreach (var key in upvalues.Keys)
            {
                LuaObject upvalue = _snapInfo.GetLuaObject(upvalues[key]);
                refLuaInfos.Add(upvalue);
            }

            _refLuaInfoListControl.SetLuaObjects(refLuaInfos);
            _childLuaInfoListControl.SetLuaObjects(childLuaInfos);
        }

        private void ShowDetailTotalInfo(int depth)
        {
            _luaObjectDetailTotalInfo.SetDepth(depth);
            string info = "";
            info += "递归层数:" + _luaObjectDetailTotalInfo.GetDepth() + "\r\n";
            info += "孩子table数" + _luaObjectDetailTotalInfo.GetChildCount() + "\r\n";
            info += "孩子table大小" + _luaObjectDetailTotalInfo.GetChildSize() + "\r\n";
            LuaItemInfoTextBox.Text = info;
        }


        public void SetLuaObject(LuaObject luaObject,SnapInfo snapInfo)
        {
            _luaObject = luaObject;
            _snapInfo = snapInfo;
        }

        private void DepthComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            ShowDetailTotalInfo(DepthComboBox.SelectedIndex + 1);
        }

    }


    public class LuaObjectDetailTotalInfo
    {
        private int _depth = 0;
        private int _childCount = 0;
        private double _childSize = 0.0f;
        private LuaObject _luaObject;
        private SnapInfo _snapInfo;
        private Dictionary<string, bool> _markDic = new Dictionary<string, bool>();

        public LuaObjectDetailTotalInfo(LuaObject luaObject, SnapInfo snapInfo)
        {
            _luaObject = luaObject;
            _snapInfo = snapInfo;
        }

        private void CreatInfo()
        {
            CalcChild(_luaObject, 0);
        }

        private void CalcChild(LuaObject luaObject, int depth)
        {
            if (depth >= _depth)
                return;
            Dictionary<string, string> childs = luaObject.GetChilds();
            _childCount += childs.Count;
            foreach (var key in childs.Keys)
            {
                LuaObject child = _snapInfo.GetLuaObject(childs[key]);
                if (!_markDic.ContainsKey(childs[key]) || !_markDic[childs[key]])
                {
                    _childSize += child.Size;
                    _markDic[childs[key]] = true;
                    CalcChild(child, depth + 1);
                }

            }

        }

        public void SetDepth(int depth)
        {
            Clear();
            _depth = depth;
            CreatInfo();
        }

        private void Clear()
        {
            _markDic.Clear();
            _childCount = 0;
            _childSize = 0.0f;
        }

        public int GetChildCount()
        {
            return _childCount;
        }

        public double GetChildSize()
        {
            return _childSize;
        }

        public int GetDepth()
        {
            return _depth;
        }
    }
}
